#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <hostmap.h>

#define CMP_STR		'='

/*获取并处理配置文件中的一行。*/
static int get_conf_line(char *buf, size_t num);
/*去除buf中的空格和换行。*/
static int str_trim(char *buf, size_t bufsize);

/*初始化被管主机表模块*/
int init_hostmap(void)
{
	int i;

	host_num_all = 0;
	for (i = 0; i < HOST_TABLE_NUM; i++) {
		host_table_all[i].enable = 0;
	}

	return 0;
}

/*读取主机表配置文件*/
int read_host_conf(void)
{
	FILE *fp;
	char *path;
	int ret;
	char *linebuf;
	size_t linenum;

	path = CONF_PATH""CONF_HOSTMAP_FILE;
	fp = fopen(path, "r");
	if (fp == NULL) {
		perror("fopen()");
		return -1;
	}

	linebuf = NULL;
	linenum = 0;
	while (1) {
		ret = getline(&linebuf, &linenum, fp);
		if (ret == -1) {
			if (feof(fp) == 0) {			//fp isn't End of File, so it's error.
				return -1;
			}
			break;					//End of file
		}

		ret = get_conf_line(linebuf, strlen(linebuf) + 1);
		if (ret == -1) {
			continue;
		}
	}

	free(linebuf);
	return 0;
}

/*获取主机信息*/
int get_hostinfo(const int host_map, struct host_info *infop)
{
	if (host_table_all[host_map].enable != 1) {
		return -1;
	}

	strncpy(infop->hostname, host_table_all[host_map].info.hostname, HOST_MAX_LEN);
	strncpy(infop->ipaddr, host_table_all[host_map].info.ipaddr, IP_ADDR_LEN);

	return 0;
}

/*保存，更新主机信息*/
int save_hostinfo(const struct host_info *infop)
{
	if (host_num_all >= HOST_TABLE_NUM || host_num_all < 0) {
		return -1;
	}

	host_table_all[host_num_all].enable = 1;
	strncpy(host_table_all[host_num_all].info.hostname, infop->hostname, HOST_MAX_LEN);
	strncpy(host_table_all[host_num_all].info.ipaddr, infop->ipaddr, IP_ADDR_LEN);

	host_num_all++;

	return 0;
}

/*获取IP地址为ipaddr的主机的host_map*/
int get_hostmap(char *ipaddr)
{
	int i, ret;

	for (i = 0; i < host_num_all; i++) {
		ret = strncmp(ipaddr, host_table_all[i].info.ipaddr, IP_ADDR_LEN);
		if (ret == 0) {
			return i;
		}
	}

	return -1;
}

/*获取并处理配置文件中的一行。*/
static int get_conf_line(char *buf, size_t num)
{
	struct host_info hinfo;
	char *ch;
	int ret, no;

	if (num == 1) {					//blank line
		return 0;
	}
	if (buf[0] == REMARK_STR) {			//注释行
		return 0;
	}

	ret = str_trim(buf, num);			//去点空格和换行
	if (ret == -1) {
		return -1;
	}
	ch = strchr(buf, CMP_STR);
	if (ch == NULL) {
		return -1;
	}
	no = ch - &buf[0];				//获取主机名长度
	memset(&hinfo, 0, sizeof(hinfo));		//将结构体设置为0，使得strncpy后hostname，ipaddr都是以\0结尾的。`
	strncpy(hinfo.hostname, buf, (no < HOST_MAX_LEN - 1) ? no : HOST_MAX_LEN - 1);		//取no和HOST_MAX_LEN - 1的小者。
	strncpy(hinfo.ipaddr, &buf[no + 1], IP_ADDR_LEN);
	save_hostinfo(&hinfo);

	return 0;
}

/*去除buf中的空格和换行。*/
static int str_trim(char *buf, size_t bufsize)
{
	static char *tmpbuf = NULL;
	static size_t tmpsize = 0;
	char *retc;
	int i, j;

	if (bufsize > tmpsize) {
		retc = realloc(tmpbuf, bufsize);
		if (retc == NULL) {
			return -1;
		}
		tmpbuf = retc;
		tmpsize = bufsize;
	}

	for (i = 0, j = 0; i < (int)bufsize - 1; i++) {
		if (buf[i] == ' ' || buf[i] == '\n') {
			continue;
		}
		tmpbuf[j] = buf[i];
		j++;
	}

	tmpbuf[j] = '\0';
	memcpy(buf, tmpbuf, j + 1);

	return j;
}
